#include "map_horizon.h"

#include "map_height.h"

MapHorizon::MapHorizon(PNM* img) :
    Transformation(img)
{
}

MapHorizon::MapHorizon(PNM* img, ImageViewer* iv) :
    Transformation(img, iv)
{
}

PNM* MapHorizon::transform()
{
    int width  = image->width(),
        height = image->height();

    double scale     = getParameter("scale").toDouble();
    int    sun_alpha = getParameter("alpha").toInt();
    int dx, dy;

    switch (getParameter("direction").toInt())
    {
    case NORTH: dx = 0; dy = -1; break;
    case SOUTH: dx = 0; dy = 1; break;
    case EAST:  dx = 1; dy = 0; break;
    case WEST:  dx = -1; dy = 0; break;
    default:
        qWarning() << "Unknown direction!";
        dx =  0;
        dy = -1;
    }

    PNM* newImage = new PNM(width, height, QImage::Format_Indexed8);
	
	auto mheight = new MapHeight(image);
	auto height_map = mheight->transform();

	float alpha = 0;
	int curr_h;
	int ray_h;
	double dist, ray_alpha, delta;

	for (int i = 0; i < width; i++)
	{
		for (int j = 0; j < height; j++)
		{
			alpha = 0.0f;
			curr_h = qGray(height_map->pixel(i, j));

			for(int k = i + dx, l = j + dy; l < height; k+=dx, l+=dy)
			{
				if(k >= width) break;
				if(k < 0 || l < 0) break;

				ray_h = qGray(height_map->pixel(k, l));
				if(curr_h < ray_h)
				{
					dist = scale * sqrt( pow(i - k, 2) + pow(j - l, 2));
					ray_alpha = atan( (ray_h - curr_h)/dist) * 180.0f / 3.14f;
					if(ray_alpha > alpha) alpha = ray_alpha;
				}					
			}
			
			delta = alpha - sun_alpha;
			if(delta <= 0)
				newImage->setPixel(i, j, 255);
			else 
				newImage->setPixel(i, j, cos(delta*3.14f/180.0f)*255.0f);
		}
	}

    return newImage;
}
